"""
WVP-Pro集成服务
"""
import asyncio
from typing import List, Dict, Optional, Tuple
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from integrations.wvp_pro_client import WVPProClient, WVPProDevice, WVPProChannel, get_wvp_client
from repositories.camera_repository import CameraRepository
from schemas.camera import CameraStatus, CameraCreate, CameraUpdate
from models.camera import Camera
import structlog

logger = structlog.get_logger(__name__)


class WVPIntegrationService:
    """WVP-Pro集成服务"""
    
    def __init__(self, db: Session):
        self.db = db
        self.camera_repository = CameraRepository(db)
        self._wvp_client: Optional[WVPProClient] = None
    
    async def get_wvp_client(self) -> WVPProClient:
        """获取WVP-Pro客户端"""
        if self._wvp_client is None:
            self._wvp_client = await get_wvp_client()
        return self._wvp_client
    
    async def test_wvp_connection(self) -> bool:
        """测试WVP-Pro连接"""
        try:
            client = await self.get_wvp_client()
            return await client.test_connection()
        except Exception as e:
            logger.error("WVP-Pro连接测试失败", exc_info=e)
            return False
    
    async def get_wvp_server_info(self) -> Dict:
        """获取WVP-Pro服务器信息"""
        try:
            client = await self.get_wvp_client()
            return await client.get_server_info()
        except Exception as e:
            logger.error("获取WVP-Pro服务器信息失败", exc_info=e)
            return {}
    
    async def sync_devices_from_wvp(self) -> Dict[str, int]:
        """从WVP-Pro同步设备信息"""
        try:
            client = await self.get_wvp_client()
            
            # 获取WVP-Pro设备列表
            wvp_devices = await client.get_device_list()
            
            created_count = 0
            updated_count = 0
            error_count = 0
            
            for wvp_device in wvp_devices:
                try:
                    # 获取设备通道
                    channels = await client.get_device_channels(wvp_device.device_id)
                    
                    # 为每个通道创建或更新摄像头记录
                    for channel in channels:
                        camera_name = f"{wvp_device.name}-{channel.name}" if channel.name else f"{wvp_device.name}-{channel.channel_id}"
                        
                        # 检查是否已存在
                        existing_camera = self.camera_repository.get_by_name(camera_name)
                        
                        if existing_camera:
                            # 更新现有摄像头
                            update_data = CameraUpdate(
                                wvp_device_id=wvp_device.device_id,
                                wvp_channel_id=channel.channel_id,
                                latitude=channel.latitude if channel.latitude != 0 else None,
                                longitude=channel.longitude if channel.longitude != 0 else None,
                                location=channel.address or None
                            )
                            
                            self.camera_repository.update(existing_camera.id, update_data)
                            updated_count += 1
                            
                        else:
                            # 创建新摄像头
                            camera_data = CameraCreate(
                                name=camera_name,
                                location=channel.address or f"WVP设备: {wvp_device.name}",
                                latitude=channel.latitude if channel.latitude != 0 else None,
                                longitude=channel.longitude if channel.longitude != 0 else None,
                                rtsp_url=f"rtsp://placeholder/{wvp_device.device_id}/{channel.channel_id}",
                                wvp_device_id=wvp_device.device_id,
                                wvp_channel_id=channel.channel_id,
                                ai_enabled=False,
                                description=f"从WVP-Pro同步的设备，制造商: {wvp_device.manufacturer}"
                            )
                            
                            camera = self.camera_repository.create(camera_data)
                            created_count += 1
                            
                            # 更新状态
                            status = CameraStatus.ONLINE if wvp_device.online else CameraStatus.OFFLINE
                            self.camera_repository.update_status(camera.id, status)
                
                except Exception as e:
                    logger.error(f"同步设备失败", device_id=wvp_device.device_id, exc_info=e)
                    error_count += 1
            
            result = {
                "created": created_count,
                "updated": updated_count,
                "errors": error_count,
                "total_devices": len(wvp_devices)
            }
            
            logger.info("WVP-Pro设备同步完成", **result)
            return result
            
        except Exception as e:
            logger.error("WVP-Pro设备同步失败", exc_info=e)
            raise
    
    async def get_stream_url(self, camera_id: int) -> Optional[str]:
        """获取摄像头视频流地址"""
        try:
            camera = self.camera_repository.get_by_id(camera_id)
            if not camera or not camera.wvp_device_id or not camera.wvp_channel_id:
                return None
            
            client = await self.get_wvp_client()
            
            # 先尝试获取现有流
            stream_info = await client.get_play_url(camera.wvp_device_id, camera.wvp_channel_id)
            
            if stream_info and stream_info.flv:
                return stream_info.flv
            
            # 如果没有现有流，启动新流
            stream_info = await client.start_play(camera.wvp_device_id, camera.wvp_channel_id)
            
            if stream_info:
                return stream_info.flv
            
            return None
            
        except Exception as e:
            logger.error("获取WVP-Pro视频流失败", camera_id=camera_id, exc_info=e)
            return None
    
    async def get_playback_url(
        self, 
        camera_id: int, 
        start_time: datetime, 
        end_time: datetime
    ) -> Optional[str]:
        """获取录像回放地址"""
        try:
            camera = self.camera_repository.get_by_id(camera_id)
            if not camera or not camera.wvp_device_id or not camera.wvp_channel_id:
                return None
            
            client = await self.get_wvp_client()
            return await client.get_playback_url(
                camera.wvp_device_id, 
                camera.wvp_channel_id, 
                start_time, 
                end_time
            )
            
        except Exception as e:
            logger.error("获取WVP-Pro录像回放地址失败", camera_id=camera_id, exc_info=e)
            return None
    
    async def control_ptz(
        self, 
        camera_id: int, 
        command: str, 
        horizontal_speed: int = 50, 
        vertical_speed: int = 50, 
        zoom_speed: int = 50
    ) -> bool:
        """PTZ控制"""
        try:
            camera = self.camera_repository.get_by_id(camera_id)
            if not camera or not camera.wvp_device_id or not camera.wvp_channel_id:
                return False
            
            client = await self.get_wvp_client()
            return await client.ptz_control(
                camera.wvp_device_id,
                camera.wvp_channel_id,
                command,
                horizontal_speed,
                vertical_speed,
                zoom_speed
            )
            
        except Exception as e:
            logger.error("WVP-Pro PTZ控制失败", camera_id=camera_id, exc_info=e)
            return False
    
    async def update_camera_status_from_wvp(self) -> Dict[str, int]:
        """从WVP-Pro更新摄像头状态"""
        try:
            client = await self.get_wvp_client()
            
            # 获取所有有WVP设备ID的摄像头
            from schemas.camera import CameraFilters
            filters = CameraFilters()
            cameras = self.camera_repository.get_list(filters)[0]
            
            # 过滤出有WVP设备ID的摄像头
            cameras = [camera for camera in cameras if camera.wvp_device_id]
            
            updated_count = 0
            error_count = 0
            
            # 按设备ID分组
            device_cameras = {}
            for camera in cameras:
                if camera.wvp_device_id:
                    if camera.wvp_device_id not in device_cameras:
                        device_cameras[camera.wvp_device_id] = []
                    device_cameras[camera.wvp_device_id].append(camera)
            
            # 获取WVP设备状态
            for device_id, device_cameras_list in device_cameras.items():
                try:
                    device_info = await client.get_device_info(device_id)
                    
                    if device_info:
                        # 更新该设备下所有摄像头的状态
                        new_status = CameraStatus.ONLINE if device_info.online else CameraStatus.OFFLINE
                        
                        for camera in device_cameras_list:
                            if camera.status != new_status:
                                self.camera_repository.update_status(camera.id, new_status)
                                updated_count += 1
                    
                except Exception as e:
                    logger.error(f"更新设备状态失败", device_id=device_id, exc_info=e)
                    error_count += 1
            
            result = {
                "updated": updated_count,
                "errors": error_count,
                "total_cameras": len(cameras)
            }
            
            logger.info("WVP-Pro摄像头状态更新完成", **result)
            return result
            
        except Exception as e:
            logger.error("WVP-Pro摄像头状态更新失败", exc_info=e)
            raise
    
    async def get_wvp_device_list(self) -> List[Dict]:
        """获取WVP-Pro设备列表"""
        try:
            client = await self.get_wvp_client()
            wvp_devices = await client.get_device_list()
            
            devices = []
            for device in wvp_devices:
                devices.append({
                    "device_id": device.device_id,
                    "name": device.name,
                    "manufacturer": device.manufacturer,
                    "model": device.model,
                    "ip": device.ip,
                    "port": device.port,
                    "online": device.online,
                    "channel_count": device.channel_count,
                    "register_time": device.register_time,
                    "keepalive_time": device.keepalive_time
                })
            
            return devices
            
        except Exception as e:
            logger.error("获取WVP-Pro设备列表失败", exc_info=e)
            raise
    
    async def get_wvp_device_channels(self, device_id: str) -> List[Dict]:
        """获取WVP-Pro设备通道列表"""
        try:
            client = await self.get_wvp_client()
            channels = await client.get_device_channels(device_id)
            
            channel_list = []
            for channel in channels:
                channel_list.append({
                    "device_id": channel.device_id,
                    "channel_id": channel.channel_id,
                    "name": channel.name,
                    "address": channel.address,
                    "latitude": channel.latitude,
                    "longitude": channel.longitude,
                    "status": channel.status,
                    "ptz_type": channel.ptz_type
                })
            
            return channel_list
            
        except Exception as e:
            logger.error("获取WVP-Pro设备通道失败", device_id=device_id, exc_info=e)
            raise
    
    async def batch_sync_cameras(self, device_ids: List[str]) -> Dict[str, int]:
        """批量同步指定设备的摄像头"""
        try:
            client = await self.get_wvp_client()
            
            created_count = 0
            updated_count = 0
            error_count = 0
            
            for device_id in device_ids:
                try:
                    # 获取设备信息
                    device_info = await client.get_device_info(device_id)
                    if not device_info:
                        error_count += 1
                        continue
                    
                    # 获取设备通道
                    channels = await client.get_device_channels(device_id)
                    
                    for channel in channels:
                        camera_name = f"{device_info.name}-{channel.name}" if channel.name else f"{device_info.name}-{channel.channel_id}"
                        
                        existing_camera = self.camera_repository.get_by_name(camera_name)
                        
                        if existing_camera:
                            # 更新现有摄像头
                            update_data = CameraUpdate(
                                wvp_device_id=device_info.device_id,
                                wvp_channel_id=channel.channel_id,
                                latitude=channel.latitude if channel.latitude != 0 else None,
                                longitude=channel.longitude if channel.longitude != 0 else None,
                                location=channel.address or None
                            )
                            
                            self.camera_repository.update(existing_camera.id, update_data)
                            updated_count += 1
                        else:
                            # 创建新摄像头
                            camera_data = CameraCreate(
                                name=camera_name,
                                location=channel.address or f"WVP设备: {device_info.name}",
                                latitude=channel.latitude if channel.latitude != 0 else None,
                                longitude=channel.longitude if channel.longitude != 0 else None,
                                rtsp_url=f"rtsp://placeholder/{device_info.device_id}/{channel.channel_id}",
                                wvp_device_id=device_info.device_id,
                                wvp_channel_id=channel.channel_id,
                                ai_enabled=False
                            )
                            
                            camera = self.camera_repository.create(camera_data)
                            created_count += 1
                            
                            # 更新状态
                            status = CameraStatus.ONLINE if device_info.online else CameraStatus.OFFLINE
                            self.camera_repository.update_status(camera.id, status)
                
                except Exception as e:
                    logger.error(f"批量同步设备失败", device_id=device_id, exc_info=e)
                    error_count += 1
            
            result = {
                "created": created_count,
                "updated": updated_count,
                "errors": error_count,
                "total_devices": len(device_ids)
            }
            
            logger.info("WVP-Pro批量设备同步完成", **result)
            return result
            
        except Exception as e:
            logger.error("WVP-Pro批量设备同步失败", exc_info=e)
            raise


# 创建服务实例（用于向后兼容）
wvp_integration_service = None


def get_wvp_integration_service(db: Session) -> WVPIntegrationService:
    """获取WVP集成服务实例"""
    return WVPIntegrationService(db)